package com.cd2cd.code_template.service.impl;

import com.cd2cd.code_template.code_template.domain.SysGroup;
import com.cd2cd.code_template.code_template.domain.SysRelationAuth;
import com.cd2cd.code_template.code_template.domain.SysRole;
import com.cd2cd.code_template.code_template.domain.SysUser;
import com.cd2cd.code_template.code_template.domain.gen.SysGroupCriteria;
import com.cd2cd.code_template.code_template.domain.gen.SysRelationAuthCriteria;
import com.cd2cd.code_template.code_template.domain.gen.SysUserCriteria;
import com.cd2cd.code_template.code_template.mapper.SysAuthMapper;
import com.cd2cd.code_template.code_template.mapper.SysGroupMapper;
import com.cd2cd.code_template.code_template.mapper.SysRelationAuthMapper;
import com.cd2cd.code_template.configuration.constants.ServiceCode;
import com.cd2cd.code_template.configuration.security.loginUserService.LoadUserService;
import com.cd2cd.code_template.service.SysGroupService;
import com.cd2cd.code_template.util.BeanUtil;
import com.cd2cd.code_template.vo.*;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;

@Component
public class SysGroupServiceImpl implements SysGroupService {

    @Resource
    private SysGroupMapper sysGroupMapper;

    @Resource
    private SysRelationAuthMapper sysRelationAuthMapper;

    @Resource
    private SysAuthMapper sysAuthMapper;

    @Override
    public BaseRes<List<SysGroupVo>> getSysGroupList(SysGroupVo sysGroupVo) {
        BaseRes<List<SysGroupVo>> res = new BaseRes<>(ServiceCode.SUCCESS);

        SysGroupCriteria criteria = new SysGroupCriteria();

        criteria.setOrderByClause(" id desc ");

        SysGroupCriteria.Criteria criteriaCriteria = criteria.createCriteria();

        criteriaCriteria.andDelFlagEqualTo("ok");

        String name = sysGroupVo.getName();

        if (StringUtils.isNotBlank(name)) {
            criteriaCriteria.andNameLike("%" + name + "%");
        }

        long count = sysGroupMapper.countByExample(criteria);

        if (count > 0) {
            List<SysGroup> sysGroups = sysGroupMapper.selectByExample(criteria);
            List<SysGroupVo> sysGroupVos = BeanUtil.voConvertList(sysGroups, SysGroupVo.class);

            if (StringUtils.isBlank(name)) {
                sysGroupVos = getSysGroupNode(sysGroupVos,0);
            }

            res.setData(sysGroupVos);
        }

        return res;
    }


    private List<SysGroupVo> getSysGroupNode(List<SysGroupVo> sysGroupVos, Integer pid) {
        List<SysGroupVo> list = new ArrayList<>();

        for (SysGroupVo sysGroupVo : sysGroupVos) {
            if (sysGroupVo.getPid().equals(pid)) {
                Integer id = sysGroupVo.getId();
                List<SysGroupVo> sysGroupNode = getSysGroupNode(sysGroupVos, id);
                if (sysGroupNode.size() > 0) {
                    sysGroupVo.setChildren(sysGroupNode);
                }
                list.add(sysGroupVo);
            }
        }

        return list;
    }

    @Override
    public BaseRes<String> addGroup(SysGroupVo sysGroupVo) {

        Integer pid = sysGroupVo.getPid();

        SysGroup sysGroup = sysGroupMapper.selectByPrimaryKey(pid);

        String parentCode;

        if (null == sysGroup || null == (parentCode = sysGroup.getCode())) {
            sysGroupVo.setCode(String.format("-%s-",pid));
        }else {
            sysGroupVo.setCode(String.format("%s%s-",parentCode,pid));
        }

        sysGroupVo.setUpdateTime(new Date());
        sysGroupVo.setCreateTime(new Date());

        sysGroupMapper.insertSelective(sysGroupVo);

        saveAuthConfig(sysGroupVo.getId(),sysGroupVo.getAuths());

        return new BaseRes<>(ServiceCode.SUCCESS);
    }

    @Override
    public BaseRes<String> updateGroup(SysGroupVo sysGroupVo) {
        List<String> auths = sysGroupVo.getAuths();

        sysGroupVo.setUpdateTime(new Date());

        saveAuthConfig(sysGroupVo.getId(),auths);

        sysGroupMapper.updateByPrimaryKeySelective(sysGroupVo);
        return new BaseRes<>(ServiceCode.SUCCESS);
    }

    private void saveAuthConfig(Integer typeId,List<String> dataGuids) {

        SysRelationAuthCriteria criteria = new SysRelationAuthCriteria();
        criteria.createCriteria().andTypeEqualTo("group").andRelationIdEqualTo(typeId).andLoginTypeEqualTo(LoadUserService.Backend.class.getSimpleName());

        sysRelationAuthMapper.deleteByExample(criteria);

        if (null == dataGuids) {
            return;
        }

        // 插入
        for (String guid : dataGuids) {
            SysRelationAuth sysRelationAuth = new SysRelationAuth();
            sysRelationAuth.setLoginType(LoadUserService.Backend.class.getSimpleName());
            sysRelationAuth.setType("group");
            sysRelationAuth.setRelationId(typeId);
            sysRelationAuth.setAuthGuid(guid);
            sysRelationAuthMapper.insertSelective(sysRelationAuth);
        }

    }

    @Override
    public BaseRes<String> delGroup(SysGroupVo sysGroupVo) {

        Integer id = sysGroupVo.getId();

        // 判断如果有下级禁止删除
        SysGroupCriteria criteria = new SysGroupCriteria();
        criteria.createCriteria().andDelFlagEqualTo("ok").andPidEqualTo(id);
        List<SysGroup> sysGroups = sysGroupMapper.selectByExample(criteria);

        if (!CollectionUtils.isEmpty(sysGroups)) {
            return new BaseRes<>(ServiceCode.DELETE_GROUP_RELATION_FAIL);
        }

        // 判断如果用户有关联禁止删除
        int count = sysGroupMapper.haveRelation(id);
        if (count > 0) {
            return new BaseRes<>(ServiceCode.DELETE_GROUP_RELATION_FAIL);
        }

        sysGroupVo.setDelFlag("del");
        sysGroupVo.setUpdateTime(new Date());
        sysGroupMapper.updateByPrimaryKeySelective(sysGroupVo);
        return new BaseRes<>(ServiceCode.SUCCESS);
    }

    @Override
    public BaseRes<SysGroupVo> groupDetail(SysGroupVo sysGroupVo) {
        BaseRes<SysGroupVo> res = new BaseRes<>(ServiceCode.SUCCESS);

        SysGroup sysGroup = sysGroupMapper.selectByPrimaryKey(sysGroupVo.getId());

        if (null != sysGroup) {
            SysGroupVo groupVo = BeanUtil.voConvert(sysGroup, SysGroupVo.class);
            List<String> guids = sysAuthMapper.selectGuid(groupVo.getId(), "group");

            groupVo.setAuths(guids);

            res.setData(groupVo);
        }

        return res;
    }

}
